package com.edu.shiro.shiroconfig;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.edu.shiro.domain.SysUser;
import com.edu.shiro.mapper.SysUserMapper;

/**
 * 登录次数限制
 * @author Administrator
 *
 */
public class RetryLimitHashedCredentialsMatcher extends SimpleCredentialsMatcher {
	
	private static final Logger logger = LoggerFactory.getLogger(RetryLimitHashedCredentialsMatcher.class);
	
	@Autowired
	private SysUserMapper userMapper;
	
	private Cache<String, AtomicInteger> passwordRetryCache;
	
	public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager){
		passwordRetryCache = cacheManager.getCache("passwordRetryCache");
	}
	
	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		String username = (String)token.getPrincipal();
		AtomicInteger retryCount = passwordRetryCache.get(username);
		if(retryCount == null){
			//如果用户没有登录过，登录次数加一 并放入缓存
			retryCount = new AtomicInteger(0);
			passwordRetryCache.put(username, retryCount);
		}
		if(retryCount.incrementAndGet() >5){
			//如果用户登录失败次数大于5  抛出锁定用户异常 并修改数据库字段
			SysUser user = userMapper.getSysUserByname(username);
			if(user != null && "0".equals(user.getStatus())){
				user.setStatus("1");
				userMapper.updateUser(user);
			}
			logger.info("锁定用户"+user.getUserName());
			throw new LockedAccountException();	
		}
		
		boolean match = super.doCredentialsMatch(token, info);
		if(match){
			//如果正确，从缓存中将用户登录计数清除
			passwordRetryCache.remove(username);
		}
		
		
		return match;
	}
	
	
	public void	unlockAccount(String username){
		SysUser user = userMapper.getSysUserByname(username);
		if(user != null){
			user.setStatus("0");
			userMapper.updateUser(user);
			passwordRetryCache.remove(username);
		}
	}
}
